﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using mojoPortal.Web;
using System.Web;
using System.Web.UI.WebControls;
using mojoPortal.Web.UI;
using System.Web.UI;
using mojoPortal.Business;
using mojoPortal.Business.WebHelpers;
using System.Configuration;

namespace blackhouse.mojoPortalExtend {
    public class PageProvider : blackhouse.Web.PageProvider {

        #region Fields

        private mojoBasePage page_priv;
        private ICmsDataAccess dataAccess;
        private static bool useFolders = GetUseFolders();

        #endregion

        #region Properties

        private mojoBasePage page {
            get {
                if (page_priv == null)
                    page_priv = this.getCurrentPage();
                return page_priv;
            }
        }

        #endregion

        #region PageProvider Members

        public override void SetCanonicalUrl(string url) {
            //if(this.page is CmsPage) {
            //    (this.page as CmsPage).newCanonicalUrl = url;
            //}
            if (HttpContext.Current != null) {
                Page aspPage = HttpContext.Current.Handler as Page;
                if (aspPage != null) {
                    Literal canonical = aspPage.Header.FindControl("pageurl") as Literal;
                    if (canonical == null) {
                        canonical = new Literal();
                        canonical.ID = "pageurl";
                        aspPage.Header.Controls.Add(canonical);
                    }
                    if (url.StartsWith("~/"))
                        url = AdjustUrlToCurrentSite(url);
                    canonical.Text = "\n<link rel='canonical' href='"
                       + url
                       + "' />";
                }
            }
        }

        private static bool GetUseFolders() {
            if (ConfigurationManager.AppSettings["UseFoldersInsteadOfHostnamesForMultipleSites"] == null)
                return false;
            else
                return ConfigurationManager.AppSettings["UseFoldersInsteadOfHostnamesForMultipleSites"].Equals(Boolean.TrueString, StringComparison.InvariantCultureIgnoreCase);
        }

        public string GetUrlToCurrentSite(string url) {
            return PageProvider.AdjustUrlToCurrentSite(url);
        }

        public static string AdjustUrlToCurrentSite(string url) {
            return AdjustUrlToSite(CacheHelper.GetCurrentSiteSettings().SiteId, url);
        }

        public string GetUrlToSite(int siteId, string url) {
            return PageProvider.AdjustUrlToSite(siteId, url);
        }

        public static string AdjustUrlToSite(int siteId, string url) {
            url = url.TrimStart(new char[] { '~' }).TrimStart(new char[] { '/' });
            if (useFolders) {
                SiteSettings ss = CacheHelper.GetSiteSettings(siteId);
                if (ss != null) {
                    SiteFolder siteFolder = SiteFolder.GetBySite(ss.SiteGuid).FirstOrDefault();
                    if (siteFolder != null)
                        url = siteFolder.FolderName + "/" + url;
                }
            }
            url = "~/" + url;
            var p = HttpContext.Current.Handler as Page;
            return
                (p != null)
                    ? p.ResolveUrl(url)
                    : System.Web.VirtualPathUtility.ToAbsolute(url);
        }

        public string GetUrlByFunctionality(string functionality) {
            PageSettings page = this.FindCmsPageByFunctionality(functionality);
            if (page != null)
                return this.GetUrlToCurrentSite(page.Url);
            else
                return String.Empty;
        }

        public string GetUrlByFunctionality(int siteId, string functionality) {
            PageSettings page = this.FindCmsPageByFunctionality(functionality, siteId);
            if (page != null)
                return this.GetUrlToSite(siteId, page.Url);
            else
                return String.Empty;
        }

        public override void SetPageDescription(string description) {
            if (this.page != null)
                this.page.MetaDescription = description;

            if (HttpContext.Current != null) {
                Page aspPage = HttpContext.Current.Handler as Page;
                if (aspPage != null) {
                    MetaContent meta = aspPage.Header.FindControl("MetaContent") as MetaContent;
                    if (meta != null)
                        meta.Description = description;
                }
            }
        }

        public override void SetPageKeywords(string keywords) {
            if (this.page != null)
                this.page.MetaKeywordCsv = keywords;
        }

        public override void SetPageTitle(string title) {
            //if(this.page is CmsPage) {
            //    (this.page as CmsPage).newPageTitle = title;
            //}
            if (HttpContext.Current != null) {
                Page aspPage = HttpContext.Current.Handler as Page;
                if (aspPage != null) {
                    aspPage.Title = title;
                    aspPage.Items["ProviderTitle"] = title;
                }
            }
        }

        public void FormatPageTitle(params object[] obj) {
            if (HttpContext.Current != null) {
                Page aspPage = HttpContext.Current.Handler as Page;
                if (aspPage != null) {
                    aspPage.Title = this.FormatString(aspPage.Title, obj);
                    if (aspPage.Items.Contains("ProviderTitle"))
                        aspPage.Title = this.FormatString(aspPage.Items["ProviderTitle"].ToString(), obj);
                }
            }
        }

        private string FormatString(string val, object[] objs) {
            for (int xo = 0; xo < objs.Length; xo++) {
                if (!val.Contains("{" + xo + "}"))
                    return val;
            }
            return string.Format(val, objs);
        }

        #endregion

        #region Methods

        private mojoBasePage getCurrentPage() {
            if (HttpContext.Current == null) return null;
            if (HttpContext.Current.Handler == null) return null;
            return HttpContext.Current.Handler as mojoBasePage;
        }

        /// <summary>
        /// Próbuje odnaleźć w bazie mojoPortal strony o zadanym adresie url, i jeżeli jest to możliwe ustawia tytuł i pozostałe elementy zgodnie z tym co jest zapisane w CMS'ie.
        /// Pozwala to edytowanie ustawień strony z poziomu systemu CMS.
        /// </summary>
        /// <param name="url">Szukany adres url, zgodnie z przyjętym system zapisu adresów przez mojoportal, url powinien zaczynać się od ~/</param>
        /// <returns></returns>
        public bool TrySetFromCmsUrl(string url) {


            PageSettings ps = this.FindCmsPage(url);
            return this.TrySetFromCms(ps);
        }

        public bool TrySetFromCms(PageSettings page) {
            if (page != null) {
                string pageUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + "/";
                pageUrl = pageUrl + page.Url.ReplaceEx("~/", "");
                this.SetCanonicalUrl(pageUrl);
                this.SetPageDescription(page.PageMetaDescription);
                this.SetPageKeywords(page.PageMetaKeyWords);
                this.SetPageTitle(page.PageTitle);
                return true;
            } else
                return false;
        }

        public PageSettings FindCmsPage(string url) {
            if (!url.StartsWith("~/"))
                url = "~/" + url;
            ICmsDataAccess data = this.GetDataAccess();
            Guid pg = data.FindPage(url, this.GetSiteId());
            if (pg != Guid.Empty) {
                PageSettings ps = new PageSettings(pg);
                if (ps.PageGuid == pg)
                    return ps;

            }
            return null;
        }

        public PageSettings FindCmsPageByFunctionality(string functionality) {
            return this.FindCmsPageByFunctionality(functionality, this.GetSiteId());
        }

        public PageSettings FindCmsPageByFunctionality(string functionality, int siteId) {
            ICmsDataAccess data = this.GetDataAccess();
            Guid pg = data.FindPageByFunctionality(functionality, siteId);
            if (pg != Guid.Empty) {
                PageSettings ps = new PageSettings(pg);
                if (ps.PageGuid == pg)
                    return ps;

            }
            return null;
        }

        private int GetSiteId() {
            int siteId = 0;
            // force SiteID from Request
            if (HttpContext.Current != null) {
                if (!Int32.TryParse(HttpContext.Current.Request["siteId"], out siteId)) {
                    siteId = CacheHelper.GetCurrentSiteSettings().SiteId;
                }
            } else
                siteId = CacheHelper.GetCurrentSiteSettings().SiteId;
            return siteId;
        }

        public FriendlyUrl FindCmsUrlByFunctionality(string functionality) {
            return this.FindCmsUrlByFunctionality(this.GetSiteId(), functionality);
        }

        public FriendlyUrl FindCmsUrlByFunctionality(int siteId, string functionality) {
            ICmsDataAccess data = this.GetDataAccess();
            int urlId = data.FindUrlByFunctionality(functionality, siteId);
            if (urlId > 0) {
                FriendlyUrl url = new FriendlyUrl(urlId);
                return url;
            } else
                return null;
        }

        public void SetCmsPageByFunctionality(string functionality, int pageId) {
            ICmsDataAccess data = this.GetDataAccess();
            data.SetCmsPageByFunctionality(functionality, pageId);
        }

        private ICmsDataAccess GetDataAccess() {
            if (this.dataAccess == null)
                this.dataAccess = new CachedCmsDataAccess(new CmsDataAccess());
            return this.dataAccess;
        }

        #endregion

    }
}
